using k8s.KubeConfigModels;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Scalar.AspNetCore;
using StackExchange.Redis;
using SumerCoreDevOps.ControlApi.Hubs;
using SumerCoreDevOps.ControlApi.Middleware;
using SumerCoreDevOps.ControlApi.Services;
using SumerCoreDevOps.Infrastructure.Artifacts;
using SumerCoreDevOps.Infrastructure.BuildTracking;
using SumerCoreDevOps.Infrastructure.Configuration;
using SumerCoreDevOps.Infrastructure.Data;
using SumerCoreDevOps.Infrastructure.Distributed;
using SumerCoreDevOps.Infrastructure.GitTrigger;
using SumerCoreDevOps.Infrastructure.HostedServices;
using SumerCoreDevOps.Infrastructure.Identity;
using SumerCoreDevOps.Infrastructure.ImageManagement;
using SumerCoreDevOps.Infrastructure.Libraries;
using SumerCoreDevOps.Infrastructure.Logging;
using SumerCoreDevOps.Infrastructure.NodeRegistration;
using SumerCoreDevOps.Infrastructure.Realtime;
using SumerCoreDevOps.Infrastructure.Scheduling;
using SumerCoreDevOps.Infrastructure.Security;
using SumerCoreDevOps.Infrastructure.Tcp;
using SumerCoreDevOps.Infrastructure.Workflow;
using SumerCoreDevOps.Shared.Constants;
using SumerCoreDevOps.Shared.Enums;
using SumerCoreDevOps.Shared.Models.Messages;
using System.Reflection;
using System.Reflection.Metadata;
using System.Text;
using System.Threading;
using System.Xml.Linq;
using TaskScheduler = SumerCoreDevOps.Infrastructure.Scheduling.TaskScheduler;

var builder = WebApplication.CreateBuilder(args);

// 配置服务
builder.Services.AddControllers();

// SignalR 实时通信服务
builder.Services.AddSignalR();
builder.Services.AddSingleton<IRealtimeNotificationService, SignalRNotificationService>();

builder.Services.AddEndpointsApiExplorer();

// ========================================
// 🌐 CORS 配置 - 支持 SignalR 跨域
// ========================================
builder.Services.AddCors(options =>
{
    options.AddPolicy("cors", builder =>
    {
        builder
            .AllowAnyMethod()
            .AllowAnyHeader()
            .SetIsOriginAllowed(_ => true) // 允许任何来源，生产环境建议配置具体域名
            .AllowCredentials(); // SignalR 需要允许凭证
    });
});

// 3. 配置 Swagger/OpenAPI
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "SumerCore DevOps API",
        Version = "v1",
        Description = "基于 .NET 9 的分布式 CI/CD 系统 API 文档"
    });

    // JWT 认证配置
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.Http,
        Scheme = "bearer",
        BearerFormat = "JWT",
        Description = "输入 JWT 令牌进行认证（格式：Bearer {token}）",
        In = ParameterLocation.Header,
        Name = "Authorization"
    });

    options.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            Array.Empty<string>()
        }
    });
});



// FreeSQL 数据库配置
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
    ?? throw new InvalidOperationException("数据库连接字符串未配置");

builder.Services.AddSingleton(sp =>
{
    var logger = sp.GetRequiredService<ILogger<FreeSQLProvider>>();
    return new FreeSQLProvider(connectionString, logger);
});

// ========================================
// 分布式协调器配置（可选，用于多主节点模式）
// ========================================
var enableDistributedMode = builder.Configuration.GetValue<bool>("Distributed:Enabled", false);
IDistributedCoordinator? distributedCoordinator = null;
string? masterId = null;

if (enableDistributedMode)
{
    var redisConnectionString = builder.Configuration.GetValue<string>("Redis:ConnectionString")
        ?? throw new InvalidOperationException("启用分布式模式时，Redis连接字符串必须配置");

    builder.Services.AddSingleton<IDistributedCoordinator>(sp =>
    {
        var redis = ConnectionMultiplexer.Connect(redisConnectionString);
        var logger = sp.GetRequiredService<ILogger<RedisCoordinator>>();
        return new RedisCoordinator(redis, logger);
    });

    // 生成主节点ID
    var tcpServerPort = builder.Configuration.GetValue<int>("TcpServer:Port", 9090);
    masterId = $"{Environment.MachineName}:{tcpServerPort}";

    builder.Logging.AddConsole();
    builder.Services.AddLogging();
}

// TCP 服务器配置
var tcpPort = builder.Configuration.GetValue<int>("TcpServer:Port", 9090);
var aesKeyString = builder.Configuration.GetValue<string>("TcpServer:AesKey")
    ?? throw new InvalidOperationException("TCP AES密钥未配置");

// 使用EncryptionHelper安全地生成AES密钥
var salt = Encoding.UTF8.GetBytes("SumerCore-TCP"); // 固定盐值用于TCP密钥
var derivedKey = EncryptionHelper.DeriveKeyFromPassword(aesKeyString, salt);
// 截取密钥到需要的长度
var aesKey = new byte[TcpProtocolConstants.AesKeyLength];
Array.Copy(derivedKey, aesKey, Math.Min(derivedKey.Length, TcpProtocolConstants.AesKeyLength));

builder.Services.AddSingleton(sp =>
{
    var logger = sp.GetRequiredService<ILogger<TcpServer>>();

    // 如果启用了分布式模式,注入分布式协调器
    if (enableDistributedMode)
    {
        var coordinator = sp.GetRequiredService<IDistributedCoordinator>();
        return new TcpServer(logger, aesKey, coordinator, masterId);
    }

    // 否则使用单主节点模式（向后兼容）
    return new TcpServer(logger, aesKey);
});

// 凭证管理器配置
var masterKey = builder.Configuration.GetValue<string>("Security:MasterKey")
    ?? throw new InvalidOperationException("主密钥未配置");

builder.Services.AddSingleton(sp =>
{
    var logger = sp.GetRequiredService<ILogger<CredentialManager>>();
    return new CredentialManager(logger, masterKey);
});

// 工作流引擎相关服务
builder.Services.AddSingleton<WorkflowDefinitionManager>();
builder.Services.AddSingleton<WorkflowInstanceTracker>();
builder.Services.AddSingleton<WorkflowEngine>();

// 主节点管理器（仅在分布式模式下启用）
if (enableDistributedMode)
{
    builder.Services.AddSingleton(sp =>
    {
        var coordinator = sp.GetRequiredService<IDistributedCoordinator>();
        var logger = sp.GetRequiredService<ILogger<MasterNodeManager>>();
        var dbProvider = sp.GetRequiredService<FreeSQLProvider>();

        var apiHost = builder.Configuration.GetValue<string>("Hosting:Host") ?? Environment.MachineName;
        var apiPort = builder.Configuration.GetValue<int>("Hosting:Port", 5000);
        var tcpServerPort = builder.Configuration.GetValue<int>("TcpServer:Port", 9090);

        return new MasterNodeManager(coordinator, dbProvider, logger, masterId!, apiHost, tcpServerPort, apiPort);
    });

    // 注册为 Hosted Service
    builder.Services.AddHostedService(sp => sp.GetRequiredService<MasterNodeManager>());
}

// 调度器服务
builder.Services.AddSingleton(sp =>
{
    var dbProvider = sp.GetRequiredService<FreeSQLProvider>();
    var logger = sp.GetRequiredService<ILogger<NodeManager>>();
    var realtimeService = sp.GetRequiredService<IRealtimeNotificationService>();

    // 如果启用了分布式模式,注入分布式协调器
    if (enableDistributedMode)
    {
        var coordinator = sp.GetRequiredService<IDistributedCoordinator>();
        return new NodeManager(dbProvider, logger, realtimeService, coordinator);
    }

    // 否则使用单主节点模式（向后兼容）
    return new NodeManager(dbProvider, logger, realtimeService);
});
builder.Services.AddSingleton(sp =>
{
    var dbProvider = sp.GetRequiredService<FreeSQLProvider>();
    var nodeManager = sp.GetRequiredService<NodeManager>();
    var workflowEngine = sp.GetRequiredService<WorkflowEngine>();
    var tcpServer = sp.GetRequiredService<TcpServer>();
    var logger = sp.GetRequiredService<ILogger<TaskScheduler>>();
    var realtimeService = sp.GetRequiredService<IRealtimeNotificationService>();

    // 如果启用了分布式模式,注入分布式协调器
    if (enableDistributedMode)
    {
        var coordinator = sp.GetRequiredService<IDistributedCoordinator>();
        return new TaskScheduler(dbProvider, nodeManager, workflowEngine, tcpServer, logger, realtimeService, coordinator);
    }

    // 否则使用单主节点模式（向后兼容）
    return new TaskScheduler(dbProvider, nodeManager, workflowEngine, tcpServer, logger, realtimeService);
});

// 基础设施库
builder.Services.AddSingleton<GitLibrary>();
builder.Services.AddSingleton(sp =>
{
    var logger = sp.GetRequiredService<ILogger<DockerLibrary>>();
    return new DockerLibrary(logger);
});
builder.Services.AddSingleton<MavenLibrary>();
builder.Services.AddSingleton<NuGetLibrary>();

// Git 触发器与镜像管理服务
builder.Services.AddSingleton<GitTriggerRuleManager>();
builder.Services.AddSingleton<ImageTagRuleManager>();
builder.Services.AddSingleton<DockerImageService>();
builder.Services.AddSingleton<BuildHistoryManager>();

// 构建产物服务
builder.Services.AddSingleton<BuildArtifactManager>();
builder.Services.AddSingleton<ArtifactProxyDownloadService>();

// 节点操作日志服务
builder.Services.AddSingleton<NodeOperationLogManager>();

// 用户认证与授权服务
builder.Services.AddSingleton<UserManager>();
builder.Services.AddSingleton<RoleManager>();
builder.Services.AddSingleton<PermissionManager>();
builder.Services.AddSingleton<UserOperationLogManager>();

// 系统配置管理服务
builder.Services.AddSingleton<SystemConfigManager>();

// 配置通知服务
builder.Services.AddSingleton<ConfigurationNotificationService>();

// 节点建立连接令牌管理服务（Join Token Manager）
builder.Services.AddSingleton<NodeJoinTokenManager>();

// 数据初始化服务
builder.Services.AddSingleton<DataSeeder>();

// Token黑名单服务
builder.Services.AddSingleton<TokenBlacklistService>();

// 后台服务
builder.Services.AddHostedService<ArtifactCleanupHostedService>();

// ========================================
// 🔐 JWT 认证配置
// ========================================
var jwtSecretKey = builder.Configuration.GetValue<string>("Jwt:SecretKey")
    ?? throw new InvalidOperationException("JWT密钥未配置");
var jwtIssuer = builder.Configuration.GetValue<string>("Jwt:Issuer") ?? "SumerCoreDevOps";
var jwtAudience = builder.Configuration.GetValue<string>("Jwt:Audience") ?? "SumerCoreDevOpsClient";
var jwtAccessTokenExpirationMinutes = builder.Configuration.GetValue<int>("Jwt:AccessTokenExpirationMinutes", 60);
var jwtRefreshTokenExpirationDays = builder.Configuration.GetValue<int>("Jwt:RefreshTokenExpirationDays", 7);

// 注册 JWT Token 服务
builder.Services.AddSingleton(sp =>
{
    var logger = sp.GetRequiredService<ILogger<JwtTokenService>>();
    var tokenBlacklistService = sp.GetRequiredService<TokenBlacklistService>();
    return new JwtTokenService(
        logger,
        jwtSecretKey,
        jwtIssuer,
        jwtAudience,
        jwtAccessTokenExpirationMinutes,
        jwtRefreshTokenExpirationDays,
        tokenBlacklistService
    );
});

// 配置 JWT 认证
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecretKey)),
        ValidateIssuer = true,
        ValidIssuer = jwtIssuer,
        ValidateAudience = true,
        ValidAudience = jwtAudience,
        ValidateLifetime = true,
        ClockSkew = TimeSpan.Zero // 不允许时钟偏差
    };

    // 配置事件处理
    options.Events = new JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            {
                context.Response.Headers.Append("Token-Expired", "true");
            }
            return Task.CompletedTask;
        },
        // SignalR Token 验证 - 从查询字符串中获取 token
        OnMessageReceived = context =>
        {
            var accessToken = context.Request.Query["access_token"];

            // 如果请求是 SignalR Hub 连接，从查询字符串获取 token
            var path = context.HttpContext.Request.Path;
            if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hubs"))
            {
                context.Token = accessToken;
            }

            return Task.CompletedTask;
        }
    };
});

builder.Services.AddAuthorization();

// MediatR - 从 Application 层注册所有 handlers
builder.Services.AddMediatR(cfg =>
    cfg.RegisterServicesFromAssembly(typeof(SumerCoreDevOps.Application.Workflows.Queries.GetWorkflowsQuery).Assembly)
    );

var app = builder.Build();

// ========================================
// 🔐 初始化加密密钥（必须在数据库迁移之前）
// ========================================
var keyManagerLogger = app.Services.GetRequiredService<ILogger<EncryptionKeyManager>>();
var keyManager = new EncryptionKeyManager(keyManagerLogger);
var encryptionKey = keyManager.GetOrCreateEncryptionKey();

// 设置加密密钥到 EncryptionHelper
EncryptionHelper.SetEncryptionKey(encryptionKey);

app.Logger.LogInformation("==============================================");
app.Logger.LogInformation("🔐 加密系统已初始化");
if (keyManager.IsUsingEnvironmentVariable())
{
    app.Logger.LogInformation("✅ 密钥来源: 环境变量 (推荐用于生产环境)");
}
else
{
    app.Logger.LogInformation("📁 密钥来源: 文件系统 ({Path})", keyManager.GetKeyFilePath());
    app.Logger.LogWarning("⚠️  开发环境：密钥已保存到本地文件");
    app.Logger.LogWarning("🔐 生产环境：请使用环境变量或密钥管理服务");
}
app.Logger.LogInformation("==============================================");

// 配置 HTTP 请求管道
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();

    // Scalar API 文档界面
    app.MapScalarApiReference(options =>
    {
        options
            .WithTitle("SumerCore DevOps API")
            .WithTheme(ScalarTheme.Mars)
            .WithDefaultHttpClient(ScalarTarget.CSharp, ScalarClient.HttpClient)
            .WithOpenApiRoutePattern("/swagger/{documentName}/swagger.json");
    });
}



// 使用异常处理中间件
app.UseExceptionHandling();

// CORS 必须在 UseRouting 之后，在 UseAuthentication 和 UseAuthorization 之前
app.UseCors("cors");

app.UseHttpsRedirection();

// 认证和授权中间件（顺序很重要）
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

// SignalR Hub 路由
app.MapHub<DevOpsHub>("/hubs/devops");

// 初始化数据库
var dbProvider = app.Services.GetRequiredService<FreeSQLProvider>();
dbProvider.MigrateUp();
app.Logger.LogInformation("数据库迁移完成");

// 初始化系统数据（权限、管理员等）
var dataSeeder = app.Services.GetRequiredService<DataSeeder>();
var initializeAdmin = app.Configuration.GetValue<bool>("DataSeeding:InitializeAdmin", false);
var adminUsername = app.Configuration.GetValue<string>("DataSeeding:AdminUsername") ?? "admin";
var adminPassword = app.Configuration.GetValue<string>("DataSeeding:AdminPassword") ?? "Admin@123456";
var adminEmail = app.Configuration.GetValue<string>("DataSeeding:AdminEmail") ?? "admin@sumer.com";

await dataSeeder.SeedAsync(initializeAdmin, adminUsername, adminPassword, adminEmail);
app.Logger.LogInformation("系统数据初始化完成");

// 初始化系统配置
var configManager = app.Services.GetRequiredService<SystemConfigManager>();
await configManager.InitializeDefaultConfigsAsync();
app.Logger.LogInformation("系统配置初始化完成");

// 设置配置通知服务（延迟注入以避免循环依赖）
var notificationService = app.Services.GetRequiredService<ConfigurationNotificationService>();
configManager.SetNotificationService(notificationService);
app.Logger.LogInformation("配置通知服务已连接");

// 启动 TCP 服务器
var tcpServer = app.Services.GetRequiredService<TcpServer>();
var nodeManager = app.Services.GetRequiredService<NodeManager>();
var taskScheduler = app.Services.GetRequiredService<TaskScheduler>();
var operationLogManager = app.Services.GetRequiredService<NodeOperationLogManager>();
var tokenManager = app.Services.GetRequiredService<NodeJoinTokenManager>();

// 注册 TCP 消息处理器
tcpServer.OnMessageReceived += async (nodeId, messageType, body) =>
{
    long? logId = null;
    try
    {
        switch (messageType)
        {
            case TcpMessageType.NodeAuth:
                if (body is NodeAuthMessage authMsg)
                {
                    // 开始记录日志
                    var log = await operationLogManager.StartOperationAsync(
                        authMsg.NodeId.ToString(), "NodeAuth", authMsg.NodeName,
                        message: $"节点认证: {authMsg.NodeName}",
                        details: authMsg);
                    logId = log.Id;

                    // 验证节点认证
                    var (isValid, node, errorMessage) = await nodeManager.AuthenticateNodeAsync(authMsg);

                    if (!isValid || node == null)
                    {
                        app.Logger.LogWarning("节点认证失败: NodeId={NodeId}, NodeName={NodeName}, Error={Error}",
                            authMsg.NodeId, authMsg.NodeName, errorMessage);

                        // 发送认证失败响应
                        var errorResponse = new AuthResponseMessage
                        {
                            Success = false,
                            NodeId = authMsg.NodeId,
                            ErrorMessage = $"认证失败: {errorMessage}"
                        };

                        await tcpServer.SendMessageAsync(nodeId, TcpMessageType.AuthResponse, errorResponse);

                        // 完成日志记录（失败）
                        await operationLogManager.CompleteOperationAsync(logId.Value, "Failed",
                            $"节点认证失败: {errorMessage}");

                        return;
                    }

                    // 发送认证成功响应
                    var authResponse = new AuthResponseMessage
                    {
                        Success = true,
                        NodeId = node.Id,
                        NewConnectionToken = null // 暂时不刷新令牌
                    };

                    await tcpServer.SendMessageAsync(nodeId, TcpMessageType.AuthResponse, authResponse);

                    // 更新客户端ID
                    tcpServer.UpdateClientId(nodeId, node.Id);

                    // 完成日志记录
                    await operationLogManager.CompleteOperationAsync(logId.Value, "Success",
                        $"节点认证成功: {node.Id}");
                }
                break;

            case TcpMessageType.NodeRegister:
                if (body is NodeRegisterMessage registerMsg)
                {
                    // 开始记录日志
                    var log = await operationLogManager.StartOperationAsync(
                        nodeId.ToString(), "NodeRegister", registerMsg.NodeName,
                        message: $"节点注册: {registerMsg.NodeName}",
                        details: registerMsg);
                    logId = log.Id;

                    // 如果提供了建立连接令牌（Join Token），验证令牌
                    if (!string.IsNullOrEmpty(registerMsg.JoinToken))
                    {
                        var (isValid, errorMessage, token) = await tokenManager.ValidateTokenAsync(registerMsg.JoinToken);

                        if (!isValid || token == null)
                        {
                            app.Logger.LogWarning("节点注册失败 - 令牌无效: NodeKey={NodeKey}, NodeName={NodeName}, Error={Error}",
                                registerMsg.NodeKey, registerMsg.NodeName, errorMessage);

                            // 发送注册失败响应
                            var errorResponse = new RegisterResponseMessage
                            {
                                Success = false,
                                NodeId = 0,
                                Token = null,
                                TokenExpiresInSeconds = 0,
                                ErrorMessage = $"注册令牌无效: {errorMessage}"
                            };

                            await tcpServer.SendMessageAsync(nodeId, TcpMessageType.RegisterResponse, errorResponse);

                            // 完成日志记录（失败）
                            await operationLogManager.CompleteOperationAsync(logId.Value, "Failed",
                                $"节点注册失败: 令牌无效 - {errorMessage}");

                            return;
                        }

                        // 使用令牌（增加使用次数）
                        await tokenManager.UseTokenAsync(registerMsg.JoinToken, 0); // 此时还没有NodeId
                    }
                    else
                    {
                        // 检查是否要求必须提供令牌
                        var requireJoinToken = app.Configuration.GetValue<bool>("NodeRegistration:RequireJoinToken", false);
                        var allowNoTokenInDev = app.Configuration.GetValue<bool>("NodeRegistration:AllowNoTokenInDevelopment", true);
                        var isDevelopment = app.Environment.IsDevelopment();

                        if (requireJoinToken && !(isDevelopment && allowNoTokenInDev))
                        {
                            app.Logger.LogWarning("节点注册失败 - 缺少令牌: NodeKey={NodeKey}, NodeName={NodeName}",
                                registerMsg.NodeKey, registerMsg.NodeName);

                            // 发送注册失败响应
                            var errorResponse = new RegisterResponseMessage
                            {
                                Success = false,
                                NodeId = 0,
                                Token = null,
                                TokenExpiresInSeconds = 0,
                                ErrorMessage = "此服务器要求使用注册令牌。请联系管理员获取令牌。"
                            };

                            await tcpServer.SendMessageAsync(nodeId, TcpMessageType.RegisterResponse, errorResponse);

                            // 完成日志记录（失败）
                            await operationLogManager.CompleteOperationAsync(logId.Value, "Failed",
                                "节点注册失败: 缺少令牌");

                            return;
                        }

                        app.Logger.LogInformation("节点注册（无令牌）: NodeKey={NodeKey}, NodeName={NodeName}",
                            registerMsg.NodeKey, registerMsg.NodeName);
                    }

                    // 注册节点
                    var node = await nodeManager.RegisterNodeAsync(registerMsg);

                    // 如果使用了令牌，更新使用记录
                    if (!string.IsNullOrEmpty(registerMsg.JoinToken))
                    {
                        await tokenManager.UseTokenAsync(registerMsg.JoinToken, node.Id);
                    }

                    // 发送注册响应
                    var response = new RegisterResponseMessage
                    {
                        Success = true,
                        NodeId = node.Id,
                        Token = Guid.NewGuid().ToString(),
                        TokenExpiresInSeconds = 86400, // 24小时
                        ConnectionToken = node.ConnectionToken // 返回持久化连接令牌
                    };

                    await tcpServer.SendMessageAsync(nodeId, TcpMessageType.RegisterResponse, response);

                    // 更新客户端ID
                    tcpServer.UpdateClientId(nodeId, node.Id);

                    // 完成日志记录
                    await operationLogManager.CompleteOperationAsync(logId.Value, "Success",
                        $"节点注册成功: {node.Id}");
                }
                break;

            case TcpMessageType.Heartbeat:
                if (body is HeartbeatMessage heartbeatMsg)
                {
                    // 心跳日志级别设为 Debug，避免过多日志
                    await operationLogManager.LogOperationAsync(
                        nodeId.ToString(), "Heartbeat", message: "心跳", logLevel: "Debug");

                    await nodeManager.HandleHeartbeatAsync(nodeId, heartbeatMsg);

                    // 发送心跳响应
                    var response = new HeartbeatResponseMessage
                    {
                        ServerTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
                        RequireConfigUpdate = false
                    };

                    await tcpServer.SendMessageAsync(nodeId, TcpMessageType.HeartbeatResponse, response);
                }
                break;

            case TcpMessageType.StepStatusReport:
                if (body is StepStatusReportMessage statusMsg)
                {
                    // 记录任务状态报告
                    await operationLogManager.LogOperationAsync(
                        nodeId.ToString(), "TaskProgress",
                        taskId: statusMsg.TaskId.ToString(),
                        status: statusMsg.Status.ToString(),
                        message: $"任务进度: {statusMsg.Progress}%",
                        details: statusMsg);

                    await taskScheduler.HandleTaskStatusReportAsync(nodeId, statusMsg);
                }
                break;

            case TcpMessageType.LogStream:
                if (body is LogStreamMessage logMsg)
                {
                    // 记录日志流
                    await operationLogManager.LogOperationAsync(
                        nodeId.ToString(), "LogStream",
                        taskId: logMsg.TaskId.ToString(),
                        message: "收到日志流",
                        details: logMsg,
                        logLevel: "Debug");

                    await taskScheduler.HandleLogStreamAsync(nodeId, logMsg);
                }
                break;

            case TcpMessageType.CleanupResult:
                if (body is CleanupResultMessage cleanupMsg)
                {
                    // 记录清理结果
                    await operationLogManager.LogOperationAsync(
                        nodeId.ToString(), "CleanupComplete",
                        taskId: cleanupMsg.TaskId.ToString(),
                        status: cleanupMsg.Success ? "Success" : "Failed",
                        message: cleanupMsg.Success ? "清理成功" : "清理失败",
                        errorMessage: cleanupMsg.ErrorMessage,
                        details: cleanupMsg);

                    await taskScheduler.HandleCleanupResultAsync(nodeId, cleanupMsg);
                }
                break;

            case TcpMessageType.ArtifactUpload:
                if (body is ArtifactUploadMessage artifactMsg)
                {
                    // 记录产物上传
                    await operationLogManager.LogOperationAsync(
                        nodeId.ToString(), "ArtifactUpload",
                        taskId: artifactMsg.TaskId.ToString(),
                        message: $"上传构建产物: {artifactMsg.Name}",
                        details: artifactMsg,
                        logLevel: "Info");

                    // 保存产物信息到数据库
                    try
                    {
                        var artifactManager = app.Services.GetRequiredService<BuildArtifactManager>();
                        await artifactManager.CreateArtifactAsync(
                            artifactMsg.NodeId,
                            artifactMsg.TaskId,
                            artifactMsg.BuildHistoryId > 0 ? artifactMsg.BuildHistoryId : null,
                            artifactMsg.Name,
                            artifactMsg.Type,
                            artifactMsg.FileSize,
                            artifactMsg.FilePath,
                            artifactMsg.Md5Hash,
                            artifactMsg.Description);

                        app.Logger.LogInformation("构建产物已保存: TaskId={TaskId}, NodeId={NodeId}, Name={Name}",
                            artifactMsg.TaskId, artifactMsg.NodeId, artifactMsg.Name);
                    }
                    catch (Exception artifactEx)
                    {
                        app.Logger.LogError(artifactEx, "保存构建产物信息失败: TaskId={TaskId}",
                            artifactMsg.TaskId);
                    }
                }
                break;

            case TcpMessageType.ArtifactDownloadResponse:
                if (body is ArtifactDownloadResponseMessage downloadResp)
                {
                    // 转发给代理下载服务
                    var proxyDownloadService = app.Services.GetRequiredService<ArtifactProxyDownloadService>();
                    proxyDownloadService.HandleDownloadResponse(downloadResp);
                }
                break;

            default:
                app.Logger.LogWarning("未知的消息类型: {MessageType}", messageType);
                await operationLogManager.LogOperationAsync(
                    nodeId.ToString(), "Error",
                    status: "Failed",
                    message: $"未知的消息类型: {messageType}",
                    logLevel: "Warning");
                break;
        }
    }
    catch (Exception ex)
    {
        app.Logger.LogError(ex, "处理TCP消息失败: MessageType={MessageType}, NodeId={NodeId}",
            messageType, nodeId);

        // 记录错误日志
        if (logId.HasValue)
        {
            await operationLogManager.CompleteOperationAsync(logId.Value, "Failed",
                errorMessage: ex.Message);
        }
        else
        {
            await operationLogManager.LogOperationAsync(
                nodeId.ToString(), "Error",
                status: "Failed",
                message: $"处理消息失败: {messageType}",
                errorMessage: ex.Message,
                logLevel: "Error");
        }
    }
};

await tcpServer.StartAsync(tcpPort);
app.Logger.LogInformation("==============================================");
app.Logger.LogInformation("🌐 TCP服务器已启动，监听端口: {Port}", tcpPort);

if (enableDistributedMode)
{
    app.Logger.LogInformation("✅ 分布式模式: 已启用");
    app.Logger.LogInformation("📡 主节点ID: {MasterId}", masterId);
    app.Logger.LogInformation("🔗 Redis连接: 已配置");
}
else
{
    app.Logger.LogInformation("⚠️  分布式模式: 未启用（单主节点模式）");
}
app.Logger.LogInformation("==============================================");

// 应用程序关闭时清理
var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
lifetime.ApplicationStopping.Register(() =>
{
    app.Logger.LogInformation("正在关闭TCP服务器...");
    tcpServer.StopAsync().Wait();
    app.Logger.LogInformation("TCP服务器已关闭");
});

app.Logger.LogInformation("SumerCore DevOps 控制面板已启动");

app.Run();
